package com.sporch.event;

import com.sporch.project.SporchECF;
import com.sporch.project.SporchEvent;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kaaproject.kaa.client.DesktopKaaPlatformContext;
import org.kaaproject.kaa.client.Kaa;
import org.kaaproject.kaa.client.KaaClient;
import org.kaaproject.kaa.client.SimpleKaaClientStateListener;
import org.kaaproject.kaa.client.channel.KaaChannelManager;
import org.kaaproject.kaa.client.channel.KaaDataChannel;
import org.kaaproject.kaa.client.channel.ServerType;
import org.kaaproject.kaa.client.channel.TransportConnectionInfo;
import org.kaaproject.kaa.client.channel.failover.FailoverDecision;
import org.kaaproject.kaa.client.channel.failover.FailoverStatus;
import org.kaaproject.kaa.client.channel.failover.strategies.FailoverStrategy;
import org.kaaproject.kaa.client.event.EventFamilyFactory;
import org.kaaproject.kaa.client.event.FindEventListenersCallback;
import org.kaaproject.kaa.client.event.registration.UserAttachCallback;
import org.kaaproject.kaa.client.logging.strategies.RecordCountLogUploadStrategy;
import org.kaaproject.kaa.common.endpoint.gen.UserAttachResponse;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Author: czy
 * @Date: 2019/6/4 17:47
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SendMessage {
    private static KaaClient kaaClient;

    @Test
    public void  sendMessage() throws UnsupportedEncodingException, InterruptedException {
        final CountDownLatch startupLatch = new CountDownLatch(1);
        // Create the Kaa desktop context for the application.
        final DesktopKaaPlatformContext desktopKaaPlatformContext = new DesktopKaaPlatformContext();

        kaaClient = Kaa.newClient(desktopKaaPlatformContext, new SimpleKaaClientStateListener(){
            @Override
            public void onStarted() {
                super.onStarted();
                System.err.println("Kaa client (Event Consumer) started");
                startupLatch.countDown();
            }
            @Override
            public void onStopped() {
                super.onStopped();
                System.err.println("Kaa client (Event Consumer) stopped");
            }
        }, true);

        /*
         *  Used by log collector on each adding of the new log record in order to check whether to send logs to server.
         *  Start log upload when there is at least one record in storage.
         */
        RecordCountLogUploadStrategy strategy = new RecordCountLogUploadStrategy(1);
        strategy.setMaxParallelUploads(1);
        kaaClient.setLogUploadStrategy(strategy);

        kaaClient.start();
        startupLatch.await();

        //添加消息监听
        final EventFamilyFactory eventFamilyFactory = kaaClient.getEventFamilyFactory();
        //Get ECF object
        SporchECF sporchECF = eventFamilyFactory.getSporchECF();
        sporchECF.addListener((event,source)->{

            System.err.println("来自app端消息:");
            System.err.println(event+"======="+source);
            writeFile(event+"======="+source);
        });

        attachUserandEmitEvents();

        send(sporchECF);




    }

    public void attachUserandEmitEvents() {
        try {
            final CountDownLatch attachLatch = new CountDownLatch(1);
            // attach user
            kaaClient.attachUser("78a35130bd3b", getMD5("SPORCH_78a35130bd3b")+"_84258741670282877186", new UserAttachCallback() {
                @Override
                public void onAttachResult(final UserAttachResponse response) {
                    System.out.println("Attach response" + response.getResult());
                    attachLatch.countDown();
                }
            });
            attachLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void send(SporchECF sporchECF){
        CountDownLatch countDownLatch = new CountDownLatch(1);
        SporchEvent sporchEvent = new SporchEvent("2222","192.168.0.120","手机110","测试消息"+getCurrentTime());
        List<String> FQNs = new LinkedList<>();
        FQNs.add(SporchEvent.class.getName());
        System.err.println("本机地址"+kaaClient.getEndpointKeyHash());

        kaaClient.findEventListeners(FQNs, new FindEventListenersCallback() {
            @Override
            public void onEventListenersReceived(List<String> eventListeners) {
//                sporchECF.sendEvent(sporchEvent,"21UyYzi0bWL5CrAggTU4xhRytXo=");
//                sporchECF.sendEventToAll(sporchEvent);
                for (String eventListener : eventListeners) {
                    System.err.println(eventListener);
                    sporchECF.sendEvent(sporchEvent,eventListener);
                }
                kaaClient.resume();
            }
            @Override
            public void onRequestFailed() {
                System.err.println("出现了错误");
            }
        });
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //将事件发送给指定端点AYjSl0XcVUVRsXlj2ONXnAwJSnI=
//        sporchECF.sendEvent(sporchEvent,"GYw/2sz88JKJwp7AWS0bmea2pcY=");
        //将事件发送给所有端点
//        sporchECF.sendEventToAll(sporchEvent);

        //使用MongoDB记录发送的数据
//        kaaClient.addLogRecord(sporchEvent);
    }

    public void removeKey(){
        System.err.println("方法调用了");
        File file1= new File("key.private");
        if (file1.exists()){
            file1.delete();
        }

        File file2= new File("key.public");
        if (file2.exists()){
            file2.delete();
        }
    }

    /**
     * 系统自带MD5
     * 默认使用大写
     * @param pInput
     * @return
     */
    public static  String getMD5(String pInput) {
        try {
            MessageDigest lDigest = MessageDigest.getInstance("MD5");
            lDigest.update(pInput.getBytes());
            BigInteger lHashInt = new BigInteger(1, lDigest.digest());
            return String.format("%1$032X", lHashInt);
        } catch (NoSuchAlgorithmException lException) {
            throw new RuntimeException(lException);
        }
    }

    public static String getCurrentTime(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        return time;
    }

    public void writeFile(String event){
        BufferedWriter bw=null;
        try {
            bw= new BufferedWriter(new FileWriter("receiveEvent.text",true));
            bw.write(event);
            bw.newLine();
            bw.flush();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
